import *  as os from 'os';
import *  as fs from 'fs';
import *  as path from 'path';
import { FileAccess } from 'vs/base/common/network';
import { execSync, spawn } from 'child_process';
import { AbortController } from "@azure/abort-controller";
import { ILogger } from 'vs/platform/log/common/log';

let showFunc: boolean = true;
export const instflag = showFunc;

export function installConfigDirPre() {
	// 获取用户目录
	const userHome = os.homedir();
	// 创建日志目录
	const configDir = `${userHome}/.config/Kylin-Code/installconfig`;
	if (!fs.existsSync(configDir)) {
		fs.mkdirSync(configDir, { recursive: true }); // 递归创建目录
	}
	return configDir;
}

//读取使用的配置文件的存放路径
// 1.如果没有selectfile.json，则使用的为/usr/share、...目录下的配置文件
// 2.如果存在selectfile.json，则使用的配置文件地址为selecDir的值
export function localConfigPath() {
	let localConfigDir = path.join(FileAccess.asFileUri('').fsPath, '..', "installwizard/config/");
	if (fs.existsSync(installConfigDirPre() + '/' + 'selectFile.json')) {
		let jsonContent = fs.readFileSync(installConfigDirPre() + '/' + 'selectFile.json', 'utf-8');
		let jsonData = JSON.parse(jsonContent);
		let selectDir = jsonData['selectDir'];
		if (selectDir && fs.existsSync(selectDir))
			return selectDir;
	}
	return localConfigDir;
}

//读取使用的配置文件的存放路径
// 1.如果没有selectfile.json，则使用的为/usr/share、...目录下的配置文件
// 2.如果存在selectfile.json，则使用的配置文件地址为selecDir的值
export function selectFileJson() {
	let selectJSON = null;
	if (fs.existsSync(installConfigDirPre() + '/' + 'selectFile.json')) {
		let jsonContent = fs.readFileSync(installConfigDirPre() + '/' + 'selectFile.json', 'utf-8');
		selectJSON = JSON.parse(jsonContent);
		return selectJSON;
	}
	return selectJSON;
}

export function getDateDir() {
	const currentD = new Date().getTime();
	// const datasttr = currentD.toLocaleDateString();
	// let name = datasttr.replace(/\//g, '')
	return currentD;
}
export function modifyJsonProperty(filePath: string, propertyName: string, newValue: string | string[]) {
	let jsonData;
	if (fs.existsSync(filePath)) {
		const fileContent = fs.readFileSync(filePath, 'utf-8');
		jsonData = JSON.parse(fileContent);
	} else {
		jsonData = {};
	}
	if (propertyName === "selectKey") {
		if (jsonData[propertyName]) {
			let tmp = jsonData[propertyName];
			tmp.push(...newValue);
			let tmparry = [...new Set(tmp)];
			jsonData[propertyName] = tmparry;
			console.log("selectKey setset:" + jsonData[propertyName]);
		} else {
			jsonData[propertyName] = newValue;
		}
	} else {
		jsonData[propertyName] = newValue;
	}

	const modifiedContent = JSON.stringify(jsonData, null, 2);
	fs.writeFileSync(filePath, modifiedContent, 'utf-8');

}
export const compareVersions = (v1: string, v2: string) => {
	if (v1 && v2) {
		return compareSegments(v1.split('.'), v2.split('.'));
	} else if (v1 || v2) {
		return v1 ? -1 : 1;
	}
	return 0;
};

const tryParse = (v: string) => {
	const n = parseInt(v, 10);
	return isNaN(n) ? v : n;
};

const forceType = (a: string | number, b: string | number) =>
	typeof a !== typeof b ? [String(a), String(b)] : [a, b];

const compareStrings = (a: string, b: string) => {
	const [ap, bp] = forceType(tryParse(a), tryParse(b));
	if (ap > bp) return 1;
	if (ap < bp) return -1;
	return 0;
};

const compareSegments = (
	a: string | string[],
	b: string | string[]
) => {
	for (let i = 0; i < Math.max(a.length, b.length); i++) {
		const r = compareStrings(a[i] || '0', b[i] || '0');
		if (r !== 0) return r;
	}
	return 0;
};
export function logDirectory() {
	const installConfigDir = installConfigDirPre();
	const logDirectory = `${installConfigDir}/log`;
	if (!fs.existsSync(logDirectory))
		fs.mkdirSync(logDirectory, { recursive: true }); // 递归创建目录
	return logDirectory;
};

export function copyFolderSync(source: string, target: string) {
	if (!fs.existsSync(target)) {
		fs.mkdirSync(target);
	}

	const files = fs.readdirSync(source);

	files.forEach((file) => {
		const sourcePath = path.join(source, file);
		const targetPath = path.join(target, file);

		if (fs.lstatSync(sourcePath).isDirectory()) {
			copyFolderSync(sourcePath, targetPath);
		} else {
			fs.copyFileSync(sourcePath, targetPath);
		}
	});
}

export function downPkgInfoToFile(dir: string, downfile: string) {
	if (!fs.existsSync(dir)) {
		console.log("fiel not ex");
		return;
	}

	fs.writeFileSync(downfile, '');
	const files = fs.readdirSync(dir);
	files.forEach((file) => {
		const filePath = path.join(dir, file);
		const { exec } = require('child_process');
		const commands = `dpkg-deb -I ${filePath}`
		exec(commands, (error: any, stdout: any, stderr: any) => {
			if (error) {
				console.log("error" + error);
				return;
			} else {
				let stdoutStr = stdout.toString();
				const lines = stdoutStr.split('\n');
				const packageName = lines.find((line: string) => line.startsWith(' Package:')).split(': ')[1];
				const packageSize = lines.find((line: string) => line.startsWith(' Installed-Size:')).split(': ')[1];
				const packageVersion = lines.find((line: string) => line.startsWith(' Version:')).split(': ')[1];
				const packgaeInfo = `${packageName} ${packageVersion} ${packageSize}\n`
				fs.appendFile(downfile, packgaeInfo, (err) => {
					if (err) {
						console.log("err" + err);
					} else {
						console.log(`package info has been appended to ${downfile} `);
					}
				})
			}
		});
	});
}

export function getInstPKGVerDpkg(pkgname: string) {
	var res = "";
	const { execSync } = require('child_process');
	try {
		var output = execSync(`dpkg -s ${pkgname} |grep "^Version"|sed 's/Version://g'|tr -d '\n'`);
		var version = output.toString().trim();
		res = version;
	}
	catch (error) { };
	return res;
}

export const moduleCancelableTask = <T>(asyncFn: (pidArry: number[]) => Promise<T>, abortcontroller: AbortController, pidArryKill: number[]) => {

	return {
		run: () => new Promise<T>((resolve, reject) => {
			const cancelTask = () => {
				if (pidArryKill.length > 0) {
					execSync(`kill -9  -${pidArryKill[pidArryKill.length - 1]}`);
				}
				reject(new Error('canceledError'));
			}

			if (abortcontroller.signal.aborted) {
				cancelTask();
				return;
			}
			asyncFn(pidArryKill).then(resolve, reject);
			abortcontroller.signal.addEventListener('abort', cancelTask);
		}),
		cancel: () => {
			abortcontroller.abort();
		},
	};
};

export function killProcessAndChildren(pid: number) {
	if (pid) {
		try {
			execSync(`kill -9  -${pid}`);
		} catch (error) {
			console.error(`杀死进程时出错: ${error}`);
		}
	}
}

export function shCancelableTask(command: string, abortcontroller: AbortController, logger: ILogger) {
	return new Promise((resolve, reject) => {
		const subprocess = spawn('sh', ['-c', command], { detached: true });
		// 监听 stdout 输出
		subprocess.stdout.on('data', (data) => {
			console.log(`stdout: ${data}`);
		});
		// 监听 stderr 输出
		subprocess.stderr.on('data', (data) => {
			console.error(`stderr: ${data}`);
		});
		// 监听进程关闭
		subprocess.on('close', (code, signal) => {
			console.log(`子进程退出，退出码 ${code},${signal}`);
			abortcontroller.signal.removeEventListener('abort', cancelTask);
			if (code === 0) {
				resolve(code);
			} else {
				reject(code);
			}
		});
		const cancelTask = () => {
			if (subprocess.pid)
				killProcessAndChildren(subprocess.pid);
		}
		abortcontroller.signal.addEventListener('abort', cancelTask);
	})

}


// function DownloadDepends(cmd: string) {
// 	return new Promise<string | number>((resolve, reject) => {
// 		const { exec } = require('child_process');
// 		exec(cmd, (error: any, stdout: string, stderr: any) => {
// 			if (error) {
// 				reject(-1);
// 			} else {
// 				let stdoutStr = stdout.toString();
// 				resolve(stdoutStr);
// 			}
// 		});
// 	});
// }
// 获取用户目录

